package menuController

import (
	"CMETO/models"
	"CMETO/utils"
	"CMETO/utils/jwt"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
)

type MenuController struct{}

// @Summary 权限查询
// @Description 分页查询权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param page query string false "页码"
// @Param pageSize query string false "尺寸"
// @Success 200 {object} models.ResultByPage[models.Menu] "查询成功"
// @Success 401 {object} models.ErrorResult "查询失败"
// @Router /menu [get]
// @Security JWT
func (m MenuController) QueryMenus(ctx *gin.Context) {
	// 获取参数，设置默认值
	page, _ := strconv.Atoi(ctx.DefaultQuery("page", "1"))
	pageSize, _ := strconv.Atoi(ctx.DefaultQuery("pageSize", "10"))
	// 定义承载体
	var menuList []models.Menu
	// 查询语句
	if err := models.DB.Where("is_delete!=1").Limit(pageSize).Offset((page - 1) * pageSize).Find(&menuList).Error; err != nil {
		ctx.JSON(http.StatusOK, models.ErrorResult{
			Msg:    "查询失败",
			Code:   "400",
			Result: err,
		})
	} else {
		// 查询条目
		var total int64
		models.DB.Table("menus").Where("is_delete!=1").Count(&total)
		ctx.JSON(http.StatusOK, &models.ResultByPage[models.Menu]{
			Msg:      "ok",
			Code:     "200",
			Page:     page,
			PageSize: pageSize,
			Total:    total,
			Result:   menuList,
		})
	}
}

// @Summary 权限查询
// @Description 根据Id查询权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param id path string true "权限id"
// @Success 200 {object} models.ResultCommon[models.Menu] "查询成功"
// @Success 401 {object} models.ErrorResult "查询失败"
// @Router /menu/{id} [get]
// @Security JWT
func (m MenuController) QueryMenuById(ctx *gin.Context) {
	menu_id := ctx.Param("id")
	var menu models.Menu
	if err := models.DB.Where("id = ? AND is_delete <> 1", menu_id).Find(&menu).Error; err != nil {
		ctx.JSON(http.StatusOK, models.ErrorResult{
			Msg:    "失败",
			Code:   "400",
			Result: err,
		})
	} else {
		ctx.JSON(http.StatusOK, models.ResultCommon[models.Menu]{
			Msg:    "ok",
			Code:   "200",
			Result: menu,
		})
	}
}

// @Summary 权限查询
// @Description 树状查询所有
// @Tags 权限管理
// @Accept json
// @Produce json
// @Success 200 {object} models.ResultCommon[models.Menu] "查询成功"
// @Success 401 {object} models.ErrorResult "查询失败"
// @Router /menu/trees [get]
// @Security JWT
func (m MenuController) QueryMenuTree(ctx *gin.Context) {

}

// 获取所有下级菜单（根据id）
func (m MenuController) QueryMenuLower(ctx *gin.Context) {

}

// @Summary 权限查询
// @Description 获取所有上级菜单
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param id path string true "权限id"
// @Success 200 {object} models.ResultCommon[[]models.Menu] "查询成功"
// @Success 401 {object} models.ErrorResult "查询失败"
// @Router /menu/upper/{id} [get]
// @Security JWT
func (m MenuController) QueryMenuUpper(ctx *gin.Context) {
	id, _ := strconv.Atoi(ctx.Param("id"))
	menuList, _ := GetAncestorMenus(id)
	ctx.JSON(http.StatusOK, models.ResultCommon[[]models.Menu]{
		Msg:    "ok",
		Code:   "200",
		Result: menuList,
	})
}

func GetAncestorMenus(id int) ([]models.Menu, error) {
	var menus []models.Menu
	err := models.DB.Model(&models.Menu{}).Where("id = ? AND is_delete = 0", id).Find(&menus).Error
	if err != nil {
		return nil, err
	}
	if len(menus) == 0 {
		return nil, err
	}
	ancestorMenus, err := GetAncestorMenus(menus[0].Fid)
	if err != nil {
		return nil, err
	}
	return append(ancestorMenus, menus...), nil
}

// @Summary 新增权限
// @Description 传入json，新增权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param MenuInfo body models.Menu true "权限信息"
// @Success 200 {object} models.AddResult "新增成功"
// @fail 400 {object} models.ErrorResult "数据错误"
// @fail 401 {object} models.AddResult "新增失败"
// @Router /menu [post]
// @Security JWT
func (m MenuController) AddMenu(ctx *gin.Context) {
	menu := &models.Menu{}
	// 绑定json数据
	if err := ctx.ShouldBindJSON(&menu); err != nil {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "参数异常",
			Code:   "400",
			Result: err,
		})
	} else {
		menu.CreateTime = utils.TimeFormatter(time.Now())
		menu.UpdateTime = utils.TimeFormatter(time.Now())
		// 从token中获取用户id
		token, _ := ctx.Get("token")
		id := token.(*jwt.MyClaims).User.Id
		menu.CreateUserId = id
		menu.UpdateUserId = id
		result := models.DB.Model(&models.Menu{}).Create(&menu).Error
		if result != nil {
			ctx.JSON(http.StatusOK, &models.AddResult{
				Msg:    "新增失败",
				Code:   "400",
				Result: 0,
			})
		} else {
			ctx.JSON(http.StatusOK, &models.AddResult{
				Msg:    "新增成功",
				Code:   "200",
				Result: 1,
			})
		}
	}
}

// @Summary 更新权限
// @Description 传入json，更新权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param MenuInfo body models.Menu true "权限信息"
// @Success 200 {object} models.UpdateResult[models.Menu] "更新成功"
// @fail 400 {object} models.ErrorResult "数据错误"
// @fail 401 {object} models.ErrorResult "更新失败"
// @Router /menu [put]
// @Security JWT
func (m MenuController) UpdateMenu(ctx *gin.Context) {
	// 定义接收数据的承载体
	var menu models.Menu
	// 绑定json数据
	if err := ctx.ShouldBindJSON(&menu); err != nil {
		ctx.JSON(http.StatusOK, &models.ErrorResult{
			Msg:    "参数异常",
			Code:   "400",
			Result: err,
		})
		return
	}
	// 从token中获取用户id
	token, _ := ctx.Get("token")
	id := token.(*jwt.MyClaims).User.Id
	menu.UpdateUserId = id
	menu.UpdateTime = utils.TimeFormatter(time.Now())
	result := models.DB.Model(&models.Menu{}).Where("id=?", menu.Id).Save(&menu).Error
	if result != nil {
		ctx.JSON(http.StatusOK, models.ErrorResult{
			Msg:    "更新失败",
			Code:   "400",
			Result: nil,
		})
	} else {
		ctx.JSON(http.StatusOK, models.UpdateResult[models.Menu]{
			Msg:    "更新成功",
			Code:   "200",
			Result: menu,
		})
	}
}

// @Summary 删除权限
// @Description 传入json，批量删除权限
// @Tags 权限管理
// @Accept json
// @Produce json
// @Param menuIds body models.DeleteParams true "权限id合集"
// @Success 200 {object} models.DeleteResult "删除成功"
// @fail 400 {object} models.ErrorResult "数据错误"
// @fail 401 {object} models.ErrorResult "删除失败"
// @Router /menu [delete]
// @Security JWT
func (m MenuController) DeleteMenu(ctx *gin.Context) {
	// 获取参数列表
	var ids models.DeleteParams
	if err := ctx.ShouldBindJSON(&ids); err != nil {
		ctx.JSON(http.StatusOK, models.ErrorResult{
			Msg:    "删除失败",
			Code:   "400",
			Result: err,
		})
	}
	var menu models.Menu
	if result := models.DB.Model(&menu).Where("id IN (?)", ids.Ids).Update("is_delete", 1); result.RowsAffected != 0 {
		ctx.JSON(http.StatusOK, models.DeleteResult{
			Msg:    "删除成功",
			Code:   "200",
			Result: ids.Ids,
		})
	} else {
		ctx.JSON(http.StatusOK, models.ErrorResult{
			Msg:    "删除失败",
			Code:   "400",
			Result: result.Error,
		})
	}
}
